<?php 
if (!function_exists('curl_init')) {
  throw new Exception('Snda needs the CURL PHP extension.');
}
if (!function_exists('json_decode')) {
  throw new Exception('Snda needs the JSON PHP extension.');
}

class OauthSDK
{
	 /** 
     * Contains the last HTTP status code returned.  
     * 
     * @ignore 
     */ 
    public $http_code; 
    /** 
     * Contains the last API call. 
     * 
     * @ignore 
     */ 
    public $url; 
    /** 
     * Set timeout default. 
     * 
     * @ignore 
     */ 
    public $timeout = 30; 
    /**  
     * Set connect timeout. 
     * 
     * @ignore 
     */ 
    public $connecttimeout = 30;  
    /** 
     * Verify SSL Cert. 
     * 
     * @ignore 
     */ 
    public $ssl_verifypeer = FALSE; 
    /** 
     * Respons format. 
     * 
     * @ignore 
     */ 
    public $format = 'json'; 
    /** 
     * Decode returned json data. 
     * 
     * @ignore 
     */ 
    public $decode_json = TRUE; 
    /** 
     * Contains the last HTTP headers returned. 
     * 
     * @ignore 
     */ 
    public $http_info; 
    /** 
     * Set the useragnet. 
     * 
     * @ignore 
     */ 
    public $useragent = 'SNDA OAuth 2.0'; 
    /* Immediately retry the API call if the response was not successful. */ 
    //public $retry = TRUE; 
    
    
  	/**
   	* The Application ID.
   	*/
  	protected $appId;

  	/**
   	* The Application API Secret.
   	*/
  	protected $appSecret;
  	
  	
  	/**
  	 * app callback url
  	 */
  	protected $redirectURI;
  	

	protected $systemParam = array(
								   "connectTimeout" => 5,
								   "timeout" => 3,
								   "gatewayUrl" => "http://test.api.snda.com:81",
								   "authorizeURL" => "http://oauth.snda.com/oauth/authorize",
								   "accessTokenURL" => "http://oauth.snda.com/oauth/token",
								   "systemTokenURL" => "http://oauth.snda.com/oauth/token",
								   );

	protected $params = array();

  	/**
  	 * 用户授权的url
  	 */
	function authorizeURL()
  	{  
		return $this->systemParam['authorizeURL'];
  	} 
  	
  	/**
  	 * 获取用户授权url
  	 */
  	function accessTokenURL()
  	{ 
		return $this->systemParam['accessTokenURL'];
  	}
  	
  	/**
  	 * 获取系统授权url
  	 */
 	function systemTokenURL()
 	{
		return $this->systemParam['systemTokenURL'];
 	}
 	
 	/**
 	 * 访问apipool
 	 */
 	function apiPoolURL()
 	{
		return $this->systemParam['gatewayUrl'];
 	}
  	
 	
  	function __construct($apiKey, $appSecret, $redirectURI)
  	{

		$this->appId = $apiKey;

  		

		$this->appSecret = $appSecret;

  		

		$this->redirectURI = $redirectURI;

  	}

	function setOption($key, $value)
	{
		$this->systemParam[$key] = $value;
	}
  	
  	
	/**
   	* Set the Application ID.
   	*
   	* @param String $appId the Application ID
   	*/
  	public function setAppId($appId)
  	{
    	$this->appId = $appId;
  	}

  	/**
   	* Get the Application ID.
   	*
   	* @return String the Application ID
   	*/
  	public function getAppId()
  	{
    	return $this->appId;
  	}
  	
  	public function setRedirectURI($redirectURI)
  	{
  		$this->redirectURI = $redirectURI;
  	}
  	
  	public function getRedirectURI()
  	{
  		return $this->redirectURI;
  	}


  	/**
   	* Set the API Secret.
   	*
   	* @param String $appId the API Secret
   	*/
  	public function setApiSecret($apiSecret)
  	{
    	$this->apiSecret = $apiSecret;
  	}

  	/**
   	* Get the API Secret.
   	*
   	* @return String the API Secret
   	*/
  	public function getApiSecret()
  	{
    	return $this->apiSecret;
  	}
  	
  	//获取accesstoken
  	public function getAccessToken($code)
  	{
  		$clientID = $this->appId;
  		$redirectURI = $this->redirectURI;
  		$clientSecret = $this->appSecret;
  		$accessTokenURL = self::accessTokenURL();
  		$url = "{$accessTokenURL}?code={$code}&client_id={$clientID}&client_secret={$clientSecret}&redirect_uri={$redirectURI}";
  		return self::http($url,'GET');
  	}
  	
  	
  	//生成请求用户授权的url
  	public function getAuthorizeURL()
  	{
  		$clientID = $this->appId;
  		$redirectURI = $this->redirectURI;
  		$authorizeURL = self::authorizeURL();
  		return "{$authorizeURL}?response_type=code&client_id={$clientID}&redirect_uri={$redirectURI}";
  	}
  	
  	
  	
  	//生成系统授权的token
  	public function getSystemToken()
  	{
  		$clientID = $this->appId;
  		$redirectURI = $this->redirectURI;
  		$clientSecret = $this->appSecret;
  		$accessTokenURL = self::accessTokenURL();
  		$url = "{$accessTokenURL}?grant_type=client_credentials&client_id={$clientID}&client_secret={$clientSecret}";
  		return self::http($url,'GET');
  	}
  	
  	static function generate_nonce()
  	{
  		//return '462d316f6f40c40a9e0eef1b009f37fa';
		$mt = microtime(); 
        $rand = mt_rand(); 

        return md5($mt . $rand); // md5s look nicer than numbers 
  	}
  	
  	/**
  	 * 请求apipool
  	 */
  	public function request($method = 'GET')
  	{
		$param = $this->params;
		$this->params = array();


  		$url = self::apiPoolURL();
        // echo "poolURL:".$url."\n";
  		$parameters['oauth_token'] = "null";
  		$parameters['oauth_consumer_key'] = $this->appId;
		$parameters['oauth_nonce'] = self::generate_nonce();
		$parameters['oauth_timestamp'] = time();
		$parameters['oauth_version'] = '2.0';
		$parameters['oauth_signature_method'] = 'HMAC-SHA1';
  		
		foreach ($parameters as $key => $value) {
			if (!isset($param[$key])) {
				$param[$key] = $parameters[$key];
			}
		}

		if (!isset($param['oauth_signature'])) {
			$param['oauth_signature'] = self::generateSig($param);
		}


  		switch($method)
  		{
  			case 'GET':
  				$url = $url."?".http_build_query($param);
  				return self::http($url,$method);
  				break;
  				
  			case 'POST':
  				$postdata = http_build_query($param);
  				return self::http($url,$method,$postdata);
  				break;
  				
  			default:
  				return 'Error http method';
  				break;
  		}
  	}
  	
	private function generateSig($params,$secret = '')
	{
		if(empty($secret))
		{
			$secret = $this->appSecret;
		}
		
    	ksort($params);
		$str="";
		foreach ($params as $k=>$v)
		{
			$str .= "$k=$v";
		}
		//$str .= $secret;
		return bin2hex(hash_hmac('sha1', $str, $secret, true));
    }
    
	function setParam($key, $value)
	{
		$this->params[$key] = $value;
	}

    /** 
     * Make an HTTP request 
     * 
     * @return string API results 
     */ 
   	function http($url, $method, $multi = false) { 

         echo "\nrequest_url:$url\n";
        $this->http_info = array(); 
        $ci = curl_init(); 
        /* Curl settings */ 
        curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); 
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); 
        curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); 
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); 
        curl_setopt($ci,CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);

        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); 
        curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); 
        curl_setopt($ci, CURLOPT_HEADER, FALSE); 

        switch ($method) { 
        case 'POST': 
            curl_setopt($ci, CURLOPT_POST, TRUE); 
            if (!empty($postfields)) { 
                curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); 
                //echo "=====post data======\r\n";
                //echo $postfields;
            } 
            break; 
        case 'DELETE': 
            curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); 
            if (!empty($postfields)) { 
                $url = "{$url}?{$postfields}"; 
            } 
        } 

        $header_array = array(); 
        $header_array2=array(); 
        foreach($header_array as $k => $v) 
        array_push($header_array2,$k.': '.$v); 

        curl_setopt($ci, CURLOPT_HTTPHEADER, $header_array2 ); 
        curl_setopt($ci, CURLINFO_HEADER_OUT, FALSE ); 

        //echo $url."<hr/>"; 

        curl_setopt($ci, CURLOPT_URL, $url); 

        $response = curl_exec($ci); 
        $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); 
        $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); 
        $this->url = $url; 
        curl_close ($ci); 
        return $response; 
    } 
    
    
    /** 
     * Get the header info to store. 
     * 
     * @return int 
     */ 
    function getHeader($ch, $header) { 
        $i = strpos($header, ':'); 
        if (!empty($i)) { 
            $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); 
            $value = trim(substr($header, $i + 2)); 
            $this->http_header[$key] = $value; 
        } 
        return strlen($header); 
    } 
  
}
?>